{- This file is part of funbot.
 -
 - Written in 2015 by fr33domlover <fr33domlover@rel4tion.org>.
 -
 - ♡ Copying is an act of love. Please copy, reuse and share.
 -
 - The author(s) have dedicated all copyright and related and neighboring
 - rights to this software to the public domain worldwide. This software is
 - distributed without any warranty.
 -
 - You should have received a copy of the CC0 Public Domain Dedication along
 - with this software. If not, see
 - <http://creativecommons.org/publicdomain/zero/1.0/>.
 -}

{-# LANGUAGE OverloadedStrings #-}

module FunBot.Sources.WebListener
    ( WebListenerSettings (..)
    , webListenerSource
    )
where

import Data.ByteString.Lazy.Char8 (empty, unpack)
import Data.Default.Class (def)
import Data.Monoid ((<>))
import Network.HTTP.Types (ok200)
import Network.HTTP.Types
import Network.Wai
import Network.Wai.Middleware.RequestLogger
import Network.Wai.Handler.Warp
import System.Log.FastLogger

import Network.IRC.Fun.Bot.Logger
import Network.IRC.Fun.Bot.State (askEnvS)

import FunBot.Sources.WebListener.Client (dispatchClient)
import FunBot.Sources.WebListener.GitLab (dispatchGitLab)
import FunBot.Sources.WebListener.Gogs (dispatchGogs)
import FunBot.Types

data WebListenerSettings = WebListenerSettings
    { -- ^ Whether to log requests in development mode
      wlsRqLogDev   :: Bool
      -- ^ Whether to allow colors in request logger, this is relevant only to
      -- the development model. It's nice when logging to terminal, but
      -- otherwise, the color codes may get written to a file and then it's
      -- probably just ugly.
    , wlsRqLogColor :: Bool
      -- ^ Logger for request logging
    , wlsRqLogger   :: LoggerSet
      -- | Path to log file for request handling errors
    , wlsErrLogFile :: FilePath
    }

listener elogger push pushMany request respond = do
    let path = rawPathInfo request
        method = parseMethod $ requestMethod request
    case (path, method) of
        ("/gogs", Right POST)   -> do
            dispatchGogs elogger push pushMany request
        ("/gitlab", Right POST) -> do
            dispatchGitLab elogger push pushMany request
        ("/client", Right POST) -> do
            dispatchClient elogger push pushMany request
        _ -> logLine elogger $
            "Web listener source: Unsupported request: " <> show (path, method)
    respond $ responseLBS ok200 [] empty

webListenerSource wls _config env push pushMany mkLogger = do
    elogger <- mkLogger $ wlsErrLogFile wls
    rlog <- mkRequestLogger def
        { outputFormat =
            if wlsRqLogDev wls
                then Detailed $ wlsRqLogColor wls
                else Apache FromSocket
        , destination = Logger $ wlsRqLogger wls
        }
    putStrLn "Bot: Web listener source listening to HTTP requests"
    run (webHookSourcePort env) $ rlog $ listener elogger push pushMany
